---
menu: Advanced
title: Custom Templates
order: 6
---

# Custom Templates

Custom templates give you the opportunity to personalize the final generated component by SVGR. In most of case you don't need it, only advanced use-cases require templates.

## Custom Component template

A custom template takes place in a file that exports a "template function".

This function is called in a babel plugin: `babel-plugin-transform-svg-component` and must returns a Babel AST. If you are not familiar with all Babel stuff, you should read [this guide](https://github.com/jamiebuilds/babel-handbook).

- `api`: The API object returned by Babel
- `opts`: Options passed to `babel-plugin-transform-svg-component`
- `astParts`: All pre-compiled parts by SVGR
  - `componentName`: The component name
  - `props`: The properties
  - `interfaces`: All necessary interfaces (typescript)
  - `imports`: All necessary imports
  - `exports`: The export of the component
  - `jsx`: The JSX part of the component

The following template is the default template used by SVGR. It is a good idea to start with it:

```js
function defaultTemplate(
  { template },
  opts,
  { imports, interfaces, componentName, props, jsx, exports },
) {
  const plugins = ['jsx']
  if (opts.typescript) {
    plugins.push('typescript')
  }
  const typeScriptTpl = template.smart({ plugins })
  return typeScriptTpl.ast`${imports}

${interfaces}

function ${componentName}(${props}) {
  return ${jsx};
}
${exports}
  `
}

module.exports = defaultTemplate
```

As you can see, we use [the `template.ast` helper of Babel](https://babeljs.io/docs/en/babel-template#template). This function have to return an AST.

Let's try something very simple. You want to add some PropTypes to your component:

```js
function propTypesTemplate(
  { template },
  opts,
  { imports, interfaces, componentName, props, jsx, exports },
) {
  const plugins = ['jsx']
  if (opts.typescript) {
    plugins.push('typescript')
  }
  const typeScriptTpl = template.smart({ plugins })
  return typeScriptTpl.ast`${imports}
import PropTypes from 'prop-types';
${interfaces}

function ${componentName}(${props}) {
  return ${jsx};
}

${componentName}.propTypes = {
  title: PropTypes.string,
};

${exports}
  `
}

module.exports = propTypesTemplate
```

As you can see it is very natural, we just add code and use AST parts in the template.

### Use with CLI

You can use component template in the CLI:

```sh
$ npx @svgr/cli --template template.js my-icon.svg
```

### Use with config

Specify the template in `.svgrrc.js`:

```js
// .svgrrc.js
module.exports = {
  template: require('./my-template'),
}
```

## Custom index template

When you use the CLI with `--out-dir` option, an index file is automatically generated.

The customization is the same, a file that exports a function:

```js
const path = require('path')

function defaultIndexTemplate(filePaths) {
  const exportEntries = filePaths.map(filePath => {
    const basename = path.basename(filePath, path.extname(filePath))
    const exportName = /^\d/.test(basename) ? `Svg${basename}` : basename
    return `export { default as ${exportName} } from './${basename}'`
  })
  return exportEntries.join('\n')
}

module.exports = defaultIndexTemplate
```

### Use with CLI

You can use component template in the CLI:

```sh
$ npx @svgr/cli --index-template index-template.js my-icon.svg
```
